let logger = require("pomelo-logger").getLogger(__filename);

const PLAYER_COLLECTION_NAME = "players";

let PlayerDao = function (app) {
    this.app = app;
};

PlayerDao.prototype.findByToken = function (token, callback) {
    let dbClient = this.app.get("gameDBClient");
    dbClient.collection(PLAYER_COLLECTION_NAME, function (error, collection) {
        if (!!error) {
            logger.error("find player failed. get collection error. error=" + error);
            callback(null);
        }
        collection.findOne({
            "token": token
        }, function (error, document) {
            if (!!error) {
                logger.error("find player failed. error = " + error);
                callback(null);
                return;
            }
            callback(document);
        });
    });
};

PlayerDao.prototype.findByChannelUid = function(channelUid, callback) {
    let dbClient = this.app.get("gameDBClient");
    dbClient.collection(PLAYER_COLLECTION_NAME, function (error, collection) {
        if (!!error) {
            logger.error("find player failed. get collection error. error=" + error);
            callback(null);
            return;
        }
        collection.findOne({
            "channelUid": channelUid
        }, function (error, document) {
            if (!!error) {
                logger.error("find player failed. error = " + error);
                callback(null);
                return;
            }
            callback(document);
        });
    });
};

PlayerDao.prototype.findByUid = function (uid, callback) {
    logger.info(`find by uid = ${uid}`);
    let dbClient = this.app.get("gameDBClient");
    dbClient.collection(PLAYER_COLLECTION_NAME, function (error, collection) {
        if (!!error) {
            logger.error("find player failed. get collection error. error=" + error);
            callback(null);
            return;
        }
        collection.findOne({
            "uid": uid
        }, function (error, document) {
            if (!!error) {
                logger.error("find player by uid failed. error =" + error);
                callback(null);
                return;
            }
            callback(document);
        })
    });
};

PlayerDao.prototype.findByUnionid = function (unionid, callback) {
    logger.info(`find by unionid = ${unionid}`);
    let dbClient = this.app.get("gameDBClient");
    dbClient.collection(PLAYER_COLLECTION_NAME, function (error, collection) {
        if (!!error) {
            logger.error("find player failed. get collection error. error=" + error);
            callback(null);
            return;
        }
        collection.findOne({
            "unionid": unionid
        }, function (error, document) {
            if (!!error) {
                logger.error("find player by unionid failed. error =" + error);
                callback(null);
                return;
            }
            callback(document);
        })
    });
};

PlayerDao.prototype.findByNickname = function (nickname, callback) {
    logger.info("find by nickname = " + nickname);
    let dbClient = this.app.get("gameDBClient");
    dbClient.collection(PLAYER_COLLECTION_NAME, function (error, collection) {
        if (!!error) {
            logger.error("find player failed. get collection error. error=" + error);
            callback(null);
            return;
        }
        collection.findOne({
            "nickname": nickname
        }, function (error, document) {
            if (!!error) {
                logger.error("find player by nickname failed. error =" + error);
                callback(null);
                return;
            }
            callback(document);
        })
    });
};

PlayerDao.prototype.findByEnabled = function (enabled, callback) {
    logger.info("find by enabled = " + enabled);
    let dbClient = this.app.get("gameDBClient");
    dbClient.collection(PLAYER_COLLECTION_NAME, function (error, collection) {
        if (!!error) {
            logger.error("find player failed. get collection error. error=" + error);
            callback(null);
            return;
        }
        collection.find({"permissionComponent.enabled": enabled})
            .sort({"uid" : -1})
            .toArray(function (error, document) {
                if (!!error) {
                    logger.error("find player by enabled failed. error =" + error);
                    callback(null);
                    return;
                }
                callback(document);
            })

    });
};

PlayerDao.prototype.insert = function (document, callback) {
    let dbClient = this.app.get("gameDBClient");
    dbClient.collection(PLAYER_COLLECTION_NAME, function (error, collection) {
        if (!!error) {
            logger.error("insert player failed. error=" + error);
            callback(null);
            return;
        }
        collection.insert(document, function (error, document) {
            if (!!error) {
                logger.error("insert player failed. error=" + error);
                callback(null);
                return;
            }
            let id = !!document.ops ? document.ops[0]._id : document[0]._id;
            callback(id);
        });
    });
};

PlayerDao.prototype.getMaxUid = function (callback) {
    let dbClient = this.app.get("gameDBClient");
    dbClient.collection(PLAYER_COLLECTION_NAME, function (error, collection) {
       if (!!error) {
           logger.error("getMaxUid failed. get collection error. error=" + error);
           callback(0);
           return;
       }
       collection.find({}, {uid: 1})
           .sort({"uid" : -1})
           .limit(1)
           .toArray(function (error, documents) {
               if (!!error) {
                   logger.error("getMaxUid failed. toArray. error=" + error);
                   callback(0);
                   return;
               }
               if (documents.length === 0) {
                   logger.warn("getMaxUid failed. document length is 0");
                   callback(0);
                   return;
               }
               callback(documents[0]["uid"] || 0);
           });
   });
};


PlayerDao.prototype.save = function (document, callback) {
    logger.info("playerDao save. document=" + JSON.stringify(document));
    let dbClient = this.app.get("gameDBClient");
    dbClient.collection(PLAYER_COLLECTION_NAME, function (error, collection) {
       if (!!error) {
           logger.error("save player failed. get collection error. error=" + error);
           callback(false);
           return;
       }
       collection.update({
           _id: document["_id"]
       }, {
           $set: document
       }, {
           safe: true
       }, function (error, affected) {
           if (!!error) {
               logger.error("save player failed. error=" + error + " document=" + JSON.stringify(document));
               callback(false);
               return;
           }
           affected = JSON.parse(affected);
           if (affected["ok"] > 0 && affected["nModified"] > 0) {
               callback(true);
           } else {
               callback(false);
           }
       });
    });
};

PlayerDao.prototype.getTopPlayTimes = function(callback) {
    let dbClient = this.app.get("gameDBClient");
    dbClient.collection(PLAYER_COLLECTION_NAME, function(error, collection) {
        if (!!error) {
            callback([]);
            return;
        }
        collection.find({'statComponent.playTimes' : {$gt : -1}} , {
            "_id": 1,
            "nickname": 1,
            "uid": 1,
            "avatar": 1,
            "channelUid": 1,
            "gender": 1,
            "description": 1,
            "statComponent.playTimes": 1
        }).sort({
            "statComponent.playTimes": -1
        }).limit(100).toArray(function(error, documents) {
            if (!!error) {
                callback([]);
                return;
            }
            callback(documents);
        });
    });
};

PlayerDao.prototype.getDiamondTopRicher = function(callback) {
    let dbClient = this.app.get("gameDBClient");
    dbClient.collection(PLAYER_COLLECTION_NAME, function(error, collection) {
        if (!!error) {
            callback([]);
            return;
        }
        collection.find({'currencyComponent.diamond' : {$gt : -1}} , {
            "_id": 1,
            "nickname": 1,
            "uid": 1,
            "avatar": 1,
            "channelUid": 1,
            "gender": 1,
            "description": 1,
            "currencyComponent.diamond": 1
        }).sort({
            "currencyComponent.diamond": -1
        }).limit(100).toArray(function(error, documents) {
            if (!!error) {
                callback([]);
                return;
            }
            callback(documents);
        });
    });
};

PlayerDao.prototype.getGoldTopRicher = function(callback) {
    let dbClient = this.app.get("gameDBClient");
    dbClient.collection(PLAYER_COLLECTION_NAME, function(error, collection) {
        if (!!error) {
            callback([]);
            return;
        }
        collection.find({'currencyComponent.gold' : {$gt : -1}} , {
            "_id": 1,
            "nickname": 1,
            "uid": 1,
            "avatar": 1,
            "channelUid": 1,
            "gender": 1,
            "description": 1,
            "currencyComponent.gold": 1
        }).sort({
            "currencyComponent.gold": -1
        }).limit(100).toArray(function(error, documents) {
            if (!!error) {
                callback([]);
                return;
            }
            callback(documents);
        });
    });
};

PlayerDao.prototype.getPlayerRegisterInfos = function (uids, startTime, endTime, callback) {
    let dbClient = this.app.get("gameDBClient");
    dbClient.collection(PLAYER_COLLECTION_NAME, function(error, collection) {
        if (!!error) {
            logger.error("getPlayerRegisterInfos failed. get collection error. error=" + error);
            callback([]);
            return;
        }
        //
        collection.find({
            uid : {$in: uids},
            createTime : {$gt: startTime, $lt: endTime}
        }).toArray(function (error, documents) {
            if (!!error) {
                logger.error("getPlayerRegisterInfos failed. get collection error. error=" + error);
                callback([]);
                return;
            }
            callback(documents);
        });
    });
};

module.exports.create = function (app) {
    return new PlayerDao(app);
};
